﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Threading;
using System.ComponentModel;
using JsonTest1.UI;

namespace JsonTest1.Net
{
    public class FileTaskpool
    {

        private class TaskItem
        {
            public IHttpStateListener listener;
            public string url;
        }

        //#region 常量
        private const int ThreadLimitCount = 3;
        //#region



        private bool mTreadProcessing;
        private int m_count;

        Queue<TaskItem> task_queue;
        List<IRevocable> m_list;
        AutoResetEvent m_event;


        //private ThreadPool threadpool;


        public static FileTaskpool taskpool;
        public static FileTaskpool Instance()
        {
           // lock (taskpool)
           // {
                if (taskpool == null)
                {
                    taskpool = new FileTaskpool();
                }

                return taskpool;
           // }

        }

        private FileTaskpool()
        {
            mTreadProcessing = false;
            m_count = 0;
            m_event = new AutoResetEvent(false);
            m_list=new List<IRevocable>();
            task_queue = new Queue<TaskItem>();
        }


        public void AddTask(string url, IHttpStateListener listener)
        {
            TaskItem item = new TaskItem() { url = url, listener = listener };

            BackgroundWorker worker = null;
            lock (task_queue)
            {
                task_queue.Enqueue(item);
                m_count++;
                if (!mTreadProcessing)
                {
                    mTreadProcessing = true;
                    worker = new BackgroundWorker();
                }
            }

            if (worker != null)
            {
                worker.DoWork += ((send, ev) => GetData());
                worker.RunWorkerCompleted += ((send, ev) =>
                {
                    lock (task_queue)
                    {
                        mTreadProcessing = false;
                    }
                });

                worker.RunWorkerAsync();
            }

            
            
        }

        private void GetData()
        {
            while (true)
            {
                if (m_count == 0)
                {
                    m_event.WaitOne();
                }

                TaskItem item = null;

                lock (task_queue)
                {
                    if (!mTreadProcessing)
                    {
                        break;
                    }

                    if (task_queue.Count == 0)
                    {
                        break;
                    }

                    item = task_queue.Dequeue();
                    Interlocked.Decrement(ref m_count);
                }

                //do request
                HttpFile file = new HttpFile();
                if (item.listener != null)
                {
                    file.OnFileLoadFailed += ((failType, errorType, data) =>
                    {

                        if (item.listener is Page)
                        {
                            ((Page)item.listener).Dispatcher.BeginInvoke(() =>
                            {
                                item.listener.HttpFailCalback(failType, errorType, data);
                            });
                        }
                        else
                        {
                            item.listener.HttpFailCalback(failType, errorType, data);
                        }
                        
                         
                    });


                    file.OnProgressChanged += ((progress, totalProgress,  type) =>
                    {
                       // item.listener.HttpProgressChangedCalback(progress, totalProgress, type);


                        if (item.listener is Page)
                        {
                            ((Page)item.listener).Dispatcher.BeginInvoke(() =>
                            {
                                item.listener.HttpProgressChangedCalback(progress, totalProgress, type);
                            });
                        }
                        else
                        {
                            item.listener.HttpProgressChangedCalback(progress, totalProgress, type);
                        }

                    });

                    file.OnFileStreamCallback += ((stream,data) => {


                        if (item.listener is Page)
                        {
                            ((Page)item.listener).Dispatcher.BeginInvoke(() =>
                            {
                                item.listener.HttpDataStreamCalback(stream, data);
                            });
                        }
                        else
                        {
                            item.listener.HttpDataStreamCalback(stream, data);
                        }
                    });

                }


                file.ProcessCompleted += (() =>
                {
                    lock (m_list)
                    {
                        m_list.Remove(file);
                    }

                    if(m_count==0)
                    {
                        m_event.Set();
                    }

                    Interlocked.Increment(ref m_count);


                    if (item.listener != null)
                    {
                        if (item.listener is Page)
                        {
                            ((Page)item.listener).Dispatcher.BeginInvoke(() =>
                            {
                                item.listener.HttpCompleted();
                            });
                        }
                        else
                        {
                            item.listener.HttpCompleted();
                        }
                    }
                    
                });

                file.BeginLoadFile(item.url);

                lock (m_list)
                {
                    m_list.Add(file);
                }

                Thread.Sleep(1);
            }
        }

        /*
         取消所有请求
         */
        public void CancelAll()
        {
            lock (task_queue)
            {
                mTreadProcessing = false;
                task_queue.Clear();
            }

            lock (m_list)
            {

                foreach (IRevocable item in m_list)
                {
                    item.RevokeAsync();
                }

            }


        }
    }
}
